﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;

namespace KinectedMusic.Kinect
{
    public enum Gesture { GestureSwipeLeft, GestureSwipeRight }
    public class GestureDetector : ISkeletonWork
    {
        List<Entry> positionsLeftHand = new List<Entry>();
        List<Entry> positionsRightHand = new List<Entry>();
        List<IGesture> possibleGestures = new List<IGesture>();
        DateTime lastGesture = DateTime.Now;

        public event EventHandler<GestureArgs> RaiseGestureDetected;

        public GestureDetector()
        {
            CreateGestures();
        }

        private void CreateGestures()
        {
            possibleGestures.Add(new GestureSwipeLeft());
            possibleGestures.Add(new GestureSwipeRight());
        }

        public void Work(Skeleton skeleton, PostureStatus posture)
        {
            Add(skeleton.Joints[JointType.HandLeft], skeleton.Joints[JointType.HandRight]);
        }

        private void Add(Joint positionLeftHand, Joint positionRightHand)
        {
            // TODO: WHAT??? do i have one of these in the controller to stop events??? i had this at 3000.0
            if (DateTime.Now.CompareTo(lastGesture.AddMilliseconds(1700.0)) < 0)
            {
                return;
            }

            positionsLeftHand.Add(new Entry { Joint = positionLeftHand, Time = DateTime.Now });
            positionsRightHand.Add(new Entry { Joint = positionRightHand, Time = DateTime.Now });

            // have to make passed in??  what should it be??
            // add time in there?? so that so not too fast, not too slow...
            int windowSize = 40;
            if (positionsLeftHand.Count > windowSize)
            {
                positionsLeftHand.Remove(positionsLeftHand[0]);
            }

            if (positionsRightHand.Count > windowSize)
            {
                positionsRightHand.Remove(positionsRightHand[0]);
            }

            foreach (IGesture gesture in possibleGestures)
            {
                if (gesture.Detect(positionsLeftHand, positionsRightHand))
                {
                    EventHandler<GestureArgs> handler = RaiseGestureDetected;
                    if (handler != null)
                    {
                        handler(this, new GestureArgs((Gesture)gesture.GetGesture()));
                    }
                    clearEntries();
                    lastGesture = DateTime.Now;
                    return;
                }
            }
        }

        private void clearEntries()
        {

            positionsLeftHand.RemoveRange(0, positionsLeftHand.Count);
            positionsRightHand.RemoveRange(0, positionsRightHand.Count);
        }
    }
}
